/*
 * WonderCam.c
 *
 *  Created on: Dec 12, 2023
 *      Author: ChenYu
 */
#include <camera.h>

#define IIC_DELAY		1

static char result_summ[128];
static char cam_func;

static uint8_t cam_rw = 0;
static uint8_t new_func = APPLICATION_NONE;
static uint8_t new_target = 1;


/**
* @brief
* @param
* @retval
*/
void camera_timer(void)
{

}


/**
  * @brief
  * @param
  * @retval
  */
static inline uint8_t iic_sda_read(void)
{
	uint8_t BitValue;
	//delay_us(IIC_DELAY);													//延时10us，防止时序频率超过要求
	BitValue = HAL_GPIO_ReadPin(I2C_SDA_CH1_GPIO_Port, I2C_SDA_CH1_Pin);   	//读取SDA电平
	return BitValue;														//返回SDA电平
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_sda_out(uint8_t dir)//SDA输出方向配置
{
    GPIO_InitTypeDef GPIO_InitStruct;
    if(dir)
    {
		GPIO_InitStruct.Pin = I2C_SDA_CH1_Pin;
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//SDA推挽输出
		GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    }
    else
    {
    	GPIO_InitStruct.Pin = I2C_SDA_CH1_Pin;
    	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//SCL上拉输入
    	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    }
    HAL_GPIO_Init(I2C_SDA_CH1_GPIO_Port,&GPIO_InitStruct);
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_start()
{
	iic_sda_out(1);
	CAM_SDA_H;
	CAM_SCL_H;
	delay_us(IIC_DELAY);
	CAM_SDA_L;
	delay_us(IIC_DELAY);
	CAM_SCL_L;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_stop()
{
	iic_sda_out(1);
	CAM_SCL_L;
	CAM_SDA_L;
	delay_us(IIC_DELAY);
	CAM_SCL_H;
	CAM_SDA_H;
	delay_us(IIC_DELAY);
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_ack()
{
	CAM_SCL_L;
	iic_sda_out(1);
	CAM_SDA_L;
    delay_us(IIC_DELAY);
    CAM_SCL_H;
    delay_us(IIC_DELAY);
    CAM_SCL_L;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_no_ack()
{
	CAM_SCL_L;
	iic_sda_out(1);
	CAM_SDA_H;
    delay_us(IIC_DELAY);
    CAM_SCL_H;
    delay_us(IIC_DELAY);
    CAM_SCL_L;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline uint8_t iic_wait_ack()
{
	uint8_t tempTime = 0;
	iic_sda_out(0);
	CAM_SDA_H;
	delay_us(IIC_DELAY);
	CAM_SCL_H;
	delay_us(IIC_DELAY);

	while(iic_sda_read())
	{
		tempTime++;
		if(tempTime>250)
		{
			iic_stop();
			return 1;
		}
	}

	CAM_SCL_L;
	return 0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void iic_write_byte(uint8_t txd)
{
	uint8_t i=0;
	iic_sda_out(1);
	CAM_SCL_L;//拉低时钟开始数据传输
	for(i=0;i<8;i++)
	{
		if((txd&0x80)>>7)
		{
			CAM_SDA_H;
		}
		else
		{
			CAM_SDA_L;
		}
		txd<<=1;
		delay_us(IIC_DELAY);
		CAM_SCL_H;
		delay_us(IIC_DELAY); //发送数据
		CAM_SCL_L;
		delay_us(IIC_DELAY);
	}
}


/**
  * @brief
  * @param
  * @retval
  */
static inline uint8_t iic_read_byte(uint8_t ack)
{
	uint8_t i=0,receive=0;
	iic_sda_out(0);
	for(i=0;i<8;i++)
	{
		CAM_SCL_L;
		delay_us(IIC_DELAY);
		CAM_SCL_H;
		receive<<=1;//左移
		if(iic_sda_read())
		{
		   receive++;//连续读取八位
		}
		delay_us(IIC_DELAY);
	}

	if(!ack)
	{
		iic_no_ack();
	}
	else
	{
		iic_ack();
	}
	return receive;//返回读取到的字节
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int camera_read_byte(uint32_t address)  // 读
{
	uint32_t val;
	iic_start(); //启动
	iic_write_byte((CAM_DEFAULT_I2C_ADDRESS<<1)); //发送写指令
	iic_wait_ack(); //应答
	iic_write_byte(address & 0x00FFu); //寄存器地址
	iic_wait_ack(); //应答
	iic_write_byte((address >> 8) & 0x00FFu); //寄存器地址
	iic_wait_ack(); //应答
	iic_stop(); //停止
	iic_start(); //重新启动
	iic_write_byte((CAM_DEFAULT_I2C_ADDRESS<<1)+1); //发送读指令
	iic_wait_ack(); //应答
	val = iic_read_byte(0); //读取一个字节
	iic_stop(); //停止
	return val;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void camera_write_byte(uint8_t address,uint8_t val)  // 写
{
	iic_start(); //起始信号
	iic_write_byte(0xEE); //发送写指令
	iic_wait_ack(); //应答
	iic_write_byte(address); //寄存器地址
	iic_wait_ack(); //应答
	iic_write_byte(val); //写入值
	iic_wait_ack(); //应答
	iic_stop(); //停止
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int readFromAddr(uint16_t addr,  char *buf, uint16_t leng)
{
	int len = 0,i;
	for (i = 0; i < leng; i++)
	{
		*buf++ = camera_read_byte(addr++); //读取一个字节
		++len;
    }
	return len;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int writeToAddr(uint16_t addr, const uint8_t *buf, uint16_t leng)
{
	int i;
	iic_start(); //起始信号
	iic_write_byte((CAM_DEFAULT_I2C_ADDRESS<<1)); //发送写指令
	iic_wait_ack(); //应答
	iic_write_byte(addr & 0x00FFu); //寄存器地址
	iic_wait_ack(); //应答
	iic_write_byte((addr >> 8) & 0x00FFu); //寄存器地址
	for(i=0;i < leng;i++){
	iic_wait_ack(); //应答
	iic_write_byte(*buf++); //寄存器地址
	}
	iic_wait_ack(); //应答
	iic_stop(); //停止
	return leng;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool firmwareVersion(char* str) {
	readFromAddr(0x0000, str, 16);
	return true;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int cam_get_func(void)   // 当前模式
{
	char buf;
	readFromAddr(0x0035, &buf, 1);
	return (int)buf;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline void setLed(bool new_state)
{
  //byte buf[3] = {0x30, 0x00, 0x00};
	byte ns_b = new_state ? 1 : 0;
	writeToAddr(0x0030, &ns_b, 1);
}


/**
  * @brief 识别到了任意人脸
  * @param
  * @retval
  */
static inline bool anyFaceDetected() {
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return result_summ[1] > 0 ? true : false;
	}
	return false;
}


/**
  * @brief 识别到的人脸总数
  * @param
  * @retval
  */
static inline int numOfTotalFaceDetected()
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return (int)result_summ[1];
	}
	return 0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool anyLearnedFaceDetected()
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return result_summ[2] > 0 ? true : false;
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int numOfTotalLearnedFaceDetected()
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return (int)result_summ[2];
	}
	return 0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool anyUnlearnedFaceDetected()
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return result_summ[3] > 0 ? true : false;
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int numOfTotalUnlearnedFaceDetected()
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		return (int)result_summ;
	}
	return 0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool faceOfIdDetected(uint8_t id)
{
	if (cam_func == APPLICATION_FACEDETECT)
	{
		for (int i = 4; i < 4 + 29; ++i)
		{
			if (result_summ[i] == id)
			{
				return true;
			}
		}
	}
	return false;
}


/**
  * @brief 返回指定ID的人脸
  * @param
  * @retval
  */
static inline bool getFaceOfId(uint8_t id,struct   WonderCamFaceDetectResult *p)
{
	memset(p, 0, sizeof(struct  WonderCamFaceDetectResult));
	if (cam_func != APPLICATION_FACEDETECT)
	{
		return false;
	}
	for (int i = 4; i < 4 + 29; ++i)
	{
		if (result_summ[i] == id)
		{
			uint16_t index = i - 4;
			index = 0x30 + index * 16;
			readFromAddr(0x0400 + index, (void*)p, 16);
			return true;
		}
	}
	return false;
}


/**
  * @brief 返回指定序号的没有ID的人脸
  * @param
  * @retval
  */
static inline bool getFaceOfIndex(uint8_t index,struct   WonderCamFaceDetectResult *p)
{
	memset(p, 0, sizeof(struct  WonderCamFaceDetectResult));
	if (cam_func != APPLICATION_FACEDETECT)
	{
		return false;
	}
	for (int i = 4; i < 4 + 29; ++i)
	{
		if (result_summ[i] == 0xFF)
		{
			--index;
			if (index == 0)
			{
				uint16_t index_ = i - 4;
				index_ = 0x30 + index_ * 16;
				readFromAddr(0x0400 + index_, (void*)p, 16);
				return true;
			}
		}
	}
	return false;
}


/**
  * @brief 识别到任意物品
  * @param
  * @retval
  */
static inline bool anyObjDetected()
{
	if (cam_func != APPLICATION_OBJDETECT)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}

int numOfObjDetected()
{
	if (cam_func != APPLICATION_OBJDETECT)
	{
		return 0;
	}
	return (int8_t)(result_summ[1]);
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool objIdDetected(uint8_t id)
{
	if (cam_func != APPLICATION_OBJDETECT)
	{
		return false;
	}
	for (int i = 2; i < 2 + 29; ++i)
	{
		if (result_summ[i] == id)
		{
			return true;
		}
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int numOfObjIdDetected(uint8_t id)
{
	if (cam_func != APPLICATION_OBJDETECT)
	{
		return 0;
	}
	int count = 0;
	for (int i = 2; i < 2 + 29; ++i)
	{
		if (result_summ[i] == id)
		{
			++count;
		}
	}
	return count;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool objDetected(uint8_t id, uint8_t index, struct  WonderCamObjDetectResult *p)
{
	memset(p, 0, sizeof(struct  WonderCamObjDetectResult));
	if (cam_func != APPLICATION_OBJDETECT)
	{
		return false;
	}
	for(int i = 2; i < 2 + 29; ++i)
	{
		if(result_summ[i] ==id)
		{
			--index;
		}
		if(index == 0)
		{
			int r = readFromAddr(0x0800 + 48 + ((i - 2) * 16), (char*)p, 16);
			if(r != 16)
			{
				return false;
			}
			return true;
		}
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int classIdOfMaxProb()
{
	if (cam_func != APPLICATION_CLASSIFICATION)
	{
		return 0;
	}
	return (int8_t)result_summ[1];
}


/**
  * @brief
  * @param
  * @retval
  */
static inline float classMaxProb()
{
	uint16_t prob_u16;
	if (cam_func != APPLICATION_CLASSIFICATION)
	{
		return 0;
	}
	memcpy(&prob_u16, &result_summ[2], 2);
	return ((float)((int)(prob_u16))) / 10000.0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline float classProbOfId(uint8_t id)
{
	uint16_t prob_u16;
	if (cam_func != APPLICATION_CLASSIFICATION)
	{
		return 0;
	}
	memcpy(&prob_u16, &result_summ[16 + (id - 1) * 4], 2);
	return ((float)((int)(prob_u16))) / 10000.0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int featureIdOfMaxProb()
{
	if (cam_func != APPLICATION_FEATURELEARNING)
	{
		return 0;
	}
	return (int8_t)result_summ[1];
}


/**
  * @brief
  * @param
  * @retval
  */
static inline float featureMaxProb()
{
	uint16_t prob_u16;
	if (cam_func != APPLICATION_FEATURELEARNING)
	{
		return 0;
	}
	memcpy(&prob_u16, &result_summ[2], 2);
	return ((float)((int)(prob_u16))) / 10000.0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline float featureProbOfId(uint8_t id)
{
	uint16_t prob_u16;
	if (cam_func != APPLICATION_FEATURELEARNING)
	{
		return 0;
	}
	memcpy(&prob_u16, &result_summ[16 + (id - 1) * 4], 2);
	return ((float)((int)(prob_u16))) / 10000.0;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool anyTagDetected(void)
{
	if (cam_func != APPLICATION_APRILTAG)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int numOfTotalTagDetected(void)
{
	if (cam_func != APPLICATION_APRILTAG)
	{
		return 0;
	}
	return result_summ[1];
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool tagIdDetected(uint16_t id)
{
	if (cam_func != APPLICATION_APRILTAG)
	{
		return false;
	}
	int num = result_summ[1];
	for (int i=2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			return true;
		}
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline int numOfTagIdDetected(uint16_t id)
{
	int count = 0;
	if (cam_func != APPLICATION_APRILTAG)
	{
		return 0;
	}
	int num = result_summ[1];
	for (int i = 2; i < 2 +  num; ++i)
	{
		if (result_summ[i] == id)
		{
			++count;
		}
	}
	return count;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline bool tagId(uint16_t id, int index,struct  WonderCamAprilTagResult *p)
{
	memset(p, 0, 32);
	if (cam_func != APPLICATION_APRILTAG)
	{
		return false;
	}
	int num = result_summ[1];
	for (int i = 2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			--index;
			if (index == 0)
			{
				readFromAddr(0x1E00 + 0x30 + 0x32 * (i - 2), (void*)p, 32);
				return true;
			}
		}
	}
	return false;
}


/**
  * @brief 是否扫描到QRCode
  * @param
  * @retval
  */
static inline bool qrCodeDetected(void)
{
	if (cam_func != APPLICATION_QRCODE)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}


/**
  * @brief QRCode的数据长度
  * @param
  * @retval
  */
static inline int qrCodeDataLength(void)
{
	struct  WonderCamQrCodeResultSumm *p = (void*)result_summ;
	if (cam_func != APPLICATION_QRCODE)
	{
	return 0;
	}
	return (int)p->len;
}


/**
  * @brief 读取Qrcode的数据
  * @param
  * @retval
  */
static inline int qrCodeData(char *buf)
{
	int len, ret;
	struct  WonderCamQrCodeResultSumm *p = (void*)result_summ;
	len = p->len;
	buf[0] = '\0';
	if (cam_func != APPLICATION_QRCODE)
	{
		return 0;
	}
	if (!qrCodeDetected())
	{
		return 0;
	}
	ret = readFromAddr(0x1800 + 48, buf, len);

	return ret;
}


/**
  * @brief 获取二维码的数据
  * @param
  * @retval
  */
static inline int qrcode_update(void)
{
	char buf[100];
	if (qrCodeDetected()) //是否识别到了二维码
	{
	    qrCodeData(buf); //获取识别到的二维码的数据
	    xbot.camera.qrcode.t1_H = buf[0] - 48;
	    xbot.camera.qrcode.t1_M = buf[1] - 48;
	    xbot.camera.qrcode.t1_L = buf[2] - 48;

	    xbot.camera.qrcode.t2_H = buf[4] - 48;
	    xbot.camera.qrcode.t2_M = buf[5] - 48;
	    xbot.camera.qrcode.t2_L = buf[6] - 48;

		return 1;
	}
	return 0;
}


/**
  * @brief 是否扫描到barCode
  * @param
  * @retval
  */
static inline bool barCodeDetected(void)
{
	if (cam_func != APPLICATION_BARCODE)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}


/**
  * @brief BarCode的数据长度
  * @param
  * @retval
  */
static inline int barCodeDataLength(void)
{
	struct  WonderCamQrCodeResultSumm *p = (void*)result_summ;
	if (cam_func != APPLICATION_BARCODE)
	{
		return 0;
	}
	return (int)p->len;
}


/**
  * @brief 读取Barcode的数据
  * @param
  * @retval
  */
static inline int barCodeData(char *buf)
{
	int len, ret;
	struct  WonderCamQrCodeResultSumm *p = (void*)result_summ;
	len = p->len;
	buf[0] = '\0';
	if (cam_func != APPLICATION_BARCODE)
	{
		return 0;
	}
	if (!barCodeDetected())
	{
		return 0;
	}
	ret = readFromAddr(0x1C00 + 48, buf, len);
	return ret;
}


/**
  * @brief 是否识别到了颜色
  * @param
  * @retval
  */
static inline bool anyColorDetected(void)
{
	if (cam_func != APPLICATION_COLORDETECT)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}


/**
  * @brief 识别到的颜色种数
  * @param
  * @retval
  */
static inline int numOfColorDetected(void)
{
	if (cam_func != APPLICATION_COLORDETECT)
	{
		return 0;
	}
	return result_summ[1];
}


/**
  * @brief 是否识别到了指定颜色
  * @param
  * @retval
  */
static inline bool colorIdDetected(uint8_t id)
{
	int i,num;
	if (cam_func != APPLICATION_COLORDETECT)
	{
		return false;
	}
	num = result_summ[1];
	for ( i = 2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			return true;
		}
	}
	return false;
}


/**
  * @brief 获取指定的识别到的颜色的位置数据
  * @param
  * @retval
  */
static inline bool colorId(uint8_t id, struct WonderCamColorDetectResult *p)
{
	int num,i,r;
	memset(p, 0, sizeof(struct WonderCamColorDetectResult));
	if (cam_func != APPLICATION_COLORDETECT)
	{
		return false;
	}
	if (!anyColorDetected())
	{
		return false;
	}
	num = result_summ[1];
	for ( i = 2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			r = readFromAddr(0x1000 + 48 + (16 * (i - 2)), (void*)p, 16);
			return r == 16 ? true : false;
		}
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
static inline struct WonderCamColorDetectResult ColorRecognitionRP( uint8_t i)
{
	struct WonderCamColorDetectResult p;  // 颜色识别结果结构体定义
	if (anyColorDetected())  // 是否识别到顔色
	{
		if (colorIdDetected(i))
		{
			if(colorId(i, &p))
	  	    {
				//printf("[cam]: ColorDetect->[%d %d %d %d]\r\n",p.x, p.y, p.w, p.h);
				return p; //  p.x x轴偏移量， p.y y轴偏移量
	  	    }
		}
	}
	return p;
}


/**
  * @brief
  * @param
  * @retval
  */
int color_update(uint8_t id, camera_t *cam)
{
	struct WonderCamColorDetectResult p;  // 颜色识别结果结构体定义
	cam->color.target_id = 0;
	if (anyColorDetected())  // 是否识别到顔色
	{
		if (colorIdDetected(id))
		{
			if(colorId(id, &p))
	  	    {
				//printf("[cam]: ColorDetect->[%d %d %d %d]\r\n",p.x, p.y, p.w, p.h);
				cam->color.target_id = id;
				cam->color.target_x = p.x;
				cam->color.target_y = p.y;
				cam->color.target_w = p.w;
				cam->color.target_h = p.h;
				return 1; //  p.x x轴偏移量， p.y y轴偏移量
	  	    }
		}
	}
	return 0;
}


/**
  * @brief 是否识别到了线
  * @param
  * @retval
  */
static inline bool anyLineDetected(void)
{
	if (cam_func != APPLICATION_LINEFOLLOW)
	{
		return false;
	}
	return result_summ[1] > 0 ? true : false;
}


/**
  * @brief 识别到的线种数
  * @param
  * @retval
  */
static inline int numOfLineDetected(void)
{
	if (cam_func != APPLICATION_LINEFOLLOW)
	{
		return 0;
	}
	return result_summ[1];
}


/**
  * @brief 是否识别到了指定线
  * @param
  * @retval
  */
static inline bool lineIdDetected(uint8_t id)
{
	int i,num;
	if (cam_func != APPLICATION_LINEFOLLOW)
	{
		return false;
	}
	num = result_summ[1];
	for (i = 2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			return true;
		}
	}
	return false;
}


/**
  * @brief 获取指定的识别到的线位置数据
  * @param
  * @retval
  */
static inline bool lineId(uint8_t id, struct WonderCamLineResult *p)
{
	memset(p, 0, sizeof(struct WonderCamLineResult));
	if (cam_func != APPLICATION_LINEFOLLOW)
	{
		return false;
	}
	if (!anyLineDetected())
	{
		return false;
	}
	int num = result_summ[1];
	for (int i = 2; i < 2 + num; ++i)
	{
		if (result_summ[i] == id)
		{
			int r = readFromAddr(0x1400 + 48 + (16 * (i - 2)), (void*)p, 16);
			if (r != 16)
			{
				return false;
			}
			p->angle = p->angle > 90 ? p->angle - 180 : p->angle;
			p->offset = abs(p->offset) - 160;
			return true;
		}
	}
	return false;
}


/**
  * @brief
  * @param
  * @retval
  */
bool camera_set_target(uint8_t target)
{
	new_target = target;
	return 1;
}


/**
  * @brief
  * @param
  * @retval
  */
bool camera_set_func(uint8_t func)
{
	cam_rw = 1;
	new_func = func;
	return 1;
}


/**
  * @brief
  * @param
  * @retval
  */
void camera_init(void)
{
	iic_stop();
	xbot.camera.state = SYS_FLAG_STARTUP;
	setLed(true);
	//setLed(false);
	camera_set_func(APPLICATION_QRCODE);
	xbot.camera.state = SYS_FLAG_PLAY;
	printf("[cam]: cam_is_ready. func->(%d)\r\n", APPLICATION_QRCODE);
}


/**
  * @brief
  * @param
  * @retval
  */
void camera_deinit(void)
{
	setLed(false);
	camera_set_func(APPLICATION_NONE);
	xbot.camera.state = SYS_FLAG_SHUTDOWN;
}


/**
  * @brief
  * @param
  * @retval
  */
void camera_polling(void)
{
	//readFromAddr(0x0035, &cam_func, 1);
	switch(cam_rw)
	{
		case 0:
			switch (cam_func)
			{
				case APPLICATION_FACEDETECT:
					readFromAddr(0x0400, result_summ, 48);
					break;
				case APPLICATION_OBJDETECT:
					readFromAddr(0x0800, result_summ, 48);
					break;
				case APPLICATION_CLASSIFICATION:
					readFromAddr(0x0C00, result_summ, 128);
					break;
				case APPLICATION_FEATURELEARNING:
					readFromAddr(0x0E00, result_summ, 64);
					break;
				case APPLICATION_COLORDETECT:
					readFromAddr(0x1000, result_summ, 48);
					/*=====to do=====*/
					//ColorRecognitionRP(new_target);
					color_update(new_target, &xbot.camera);
					/*======end======*/
					break;
				case APPLICATION_LINEFOLLOW:
					readFromAddr(0x1400, result_summ, 48);
					break;
				case APPLICATION_APRILTAG:
					readFromAddr(0x1E00, result_summ, 48);
					break;
				case APPLICATION_QRCODE:
					readFromAddr(0x1800, result_summ, 48);
					/*=====to do=====*/
					qrcode_update();
					/*======end======*/
					break;
				case APPLICATION_BARCODE:
					readFromAddr(0x1C00, result_summ, 48);
					break;
				default:
					break;
			}
			break;
		case 1:
			static uint8_t count = 0;
			writeToAddr(0x0035, &new_func, 1);
			delay_us(50);
			while (true)
			{
				if (cam_get_func() != new_func)
				{
					delay_us(50);
				}
				else
				{
					cam_func = new_func;
					count = 0;
					cam_rw = 0;
					break;
				}
				++count;
				if (count > 80)
				{
					cam_rw = 0;
					count = 0;
					break;
				}
			}
			break;

	}
}

